﻿#include "function_frank_width.h"

// Procedures
void frankWidth (HObject ho_image, HObject *ho_region_show, HTuple hv_row1, HTuple hv_column1,
    HTuple hv_row2, HTuple hv_column2, HTuple *hv_ret, HTuple *hv_detection_column1,
    HTuple *hv_detection_column2)
{

  // Local iconic variables
  HObject  ho_Rectangle, ho_ImageReduced, ho_Region;
  HObject  ho_RegionFillUp, ho_ConnectedRegions, ho_SelectedRegions;

  // Local control variables
  HTuple  hv_UsedThreshold, hv_Number, hv_DetectionRow1;
  HTuple  hv_DetectionRow2;

  GenRectangle1(&ho_Rectangle, hv_row1, hv_column1, hv_row2, hv_column2);
  ReduceDomain(ho_image, ho_Rectangle, &ho_ImageReduced);
  BinaryThreshold(ho_ImageReduced, &ho_Region, "max_separability", "dark", &hv_UsedThreshold);
  FillUp(ho_Region, &ho_RegionFillUp);
  Connection(ho_RegionFillUp, &ho_ConnectedRegions);
  CountObj(ho_ConnectedRegions, &hv_Number);
  if (0 != (int(hv_Number==0)))
  {
    (*hv_ret) = 0;
    return;
  }
  SelectShapeStd(ho_ConnectedRegions, &ho_SelectedRegions, "max_area", 70);
  SmallestRectangle1(ho_SelectedRegions, &hv_DetectionRow1, &(*hv_detection_column1),
      &hv_DetectionRow2, &(*hv_detection_column2));
  GenRectangle1(&(*ho_region_show), hv_DetectionRow1, (*hv_detection_column1), hv_DetectionRow2,
      (*hv_detection_column2));
  (*hv_ret) = 1;

}

FunctionFrankWidth::FunctionFrankWidth(QDialog* parent, QSettings* qsettings, QString section) : QDialog(parent)
{
	QSettings* m_settings_para = new QSettings(QCoreApplication::applicationDirPath() +"/para" +"/para.ini", QSettings::IniFormat);
	m_settings_para->setIniCodec("UTF-8");
	m_save_image_dir = m_settings_para->value("para/m_save_image_dir", "").toString();


    m_qsettings = qsettings;
    m_section = section;

    this->setWindowTitle(("Frank Width"));
    QRect desktop_rect = QApplication::desktop()->geometry();
    double ratio_x = desktop_rect.width()/1920.0;
    double ratio_y = desktop_rect.height()/1080.0;

    move(0,0);
    setFixedSize(1920*ratio_x,1010*ratio_y);



    m_view = new QtQGraphicsView(this);
    m_view->setGeometry(660 * ratio_x, 0, 1000 * 1.25 * ratio_x, 800 * 1.25 * ratio_y);

	connect(m_view->m_pixmapItem, &QtQGraphicsPixmapItem::drawRectangleFinish, this, [=](QGraphicsItem* p, int draw_type)
	{
		if (draw_type == 1)
			m_vector_graphics_shape_rectangle.push_back((GraphicsShapeRectangleCirce*)p);
	});
    

    QSize control_size(220*ratio_x,40*ratio_y);

    QWidget* p = new QWidget(this);
    p->move(0*ratio_x,0*ratio_y);
    p->setFixedSize(600*ratio_x,800*ratio_y);

    QGridLayout *qgridLayout = new QGridLayout();
    p->setLayout(qgridLayout);

    int index = 0;

    QSize ButtonSize(220 * ratio_x, 40 * ratio_y);


    m_qlabel_width_min = new QLabel();
    m_qlabel_width_min->setText("Min");
    m_qlabel_width_min->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_width_min, index, 0);
    m_qspinbox_width_min = new QSpinBox();
    m_qspinbox_width_min->setFixedSize(control_size);
    m_qspinbox_width_min->setMinimum(1);
    m_qspinbox_width_min->setMaximum(10000);
    qgridLayout->addWidget(m_qspinbox_width_min, index, 1);
    index++;
    m_qlabel_width_max = new QLabel();
    m_qlabel_width_max->setText("Max");
    m_qlabel_width_max->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_width_max, index, 0);
    m_qspinbox_width_max = new QSpinBox();
    m_qspinbox_width_max->setFixedSize(control_size);
    m_qspinbox_width_max->setMinimum(1);
    m_qspinbox_width_max->setMaximum(10000);
    qgridLayout->addWidget(m_qspinbox_width_max, index, 1);
    index++;


	QPushButton* p_QPushButton = new QPushButton(this);
	p_QPushButton->setFixedSize(control_size);
    p_QPushButton->setText("Draw ROI");
	connect(p_QPushButton, &QPushButton::clicked, this, [=]() {
		m_view->m_pixmapItem->m_shape_type = 1;
		m_view->m_pixmapItem->m_color = Qt::blue;
		m_view->m_pixmapItem->m_bool_filled = false;
	});
	qgridLayout->addWidget(p_QPushButton, index, 0);
	

	p_QPushButton = new QPushButton(this);
	p_QPushButton->setFixedSize(control_size);
    p_QPushButton->setText("Delete ROI");
	qgridLayout->addWidget(p_QPushButton, index, 1);
	connect(p_QPushButton, &QPushButton::clicked, this, [=]() {
		for (GraphicsShapeRectangleCirce *item : m_vector_graphics_shape_rectangle) {
			m_view->scene()->removeItem(item);
			delete item;
		}
		m_vector_graphics_shape_rectangle.clear();
	});
	index++;

	p_QPushButton = new QPushButton(this);
	p_QPushButton->setFixedSize(control_size);
	p_QPushButton->setText("Draw Mask");
	connect(p_QPushButton, &QPushButton::clicked, this, [=]() {
		m_view->m_pixmapItem->m_shape_type = 2;
		m_view->m_pixmapItem->m_color = Qt::darkYellow;
		m_view->m_pixmapItem->m_bool_filled = true;
	});
	qgridLayout->addWidget(p_QPushButton, index, 0);



    m_pushbutton_save_parameter = new QPushButton(this);
    m_pushbutton_save_parameter->setFixedSize(control_size);
    m_pushbutton_save_parameter->setText("Save");
    connect(m_pushbutton_save_parameter, &QPushButton::clicked, this, &FunctionFrankWidth::saveParameter);
    qgridLayout->addWidget(m_pushbutton_save_parameter, index,0);
    index++;

    m_pushbutton_show_orign_image = new QPushButton(this);
    m_pushbutton_show_orign_image->setFixedSize(control_size);
    m_pushbutton_show_orign_image->setText("ShowOrign");
    connect(m_pushbutton_show_orign_image, &QPushButton::clicked, this,[=]() {
        QImage q_image = matToQImage(m_image);
        m_view->setImage(q_image,"");
        return true;
    });
    qgridLayout->addWidget(m_pushbutton_show_orign_image, index,0);

    m_pushbutton_detection = new QPushButton(this);
    m_pushbutton_detection->setFixedSize(control_size);
    m_pushbutton_detection->setText("Detection");
    connect(m_pushbutton_detection, &QPushButton::clicked, this, &FunctionFrankWidth::detectionImage);
    qgridLayout->addWidget(m_pushbutton_detection, index,1);
    index++;

    m_pushbutton_return = new QPushButton(this);
    m_pushbutton_return->setFixedSize(control_size);
    m_pushbutton_return->setText("Exit");
    qgridLayout->addWidget(m_pushbutton_return, index, 0);
    connect(m_pushbutton_return, &QPushButton::clicked, this, [=]() {
        this->hide();
        });
	index++;
    


    loadParameter();

}

FunctionFrankWidth::~FunctionFrankWidth()
{
    ;
}


int FunctionFrankWidth::detection(HObject image, QString& message)
{
    try
    {
        HTuple hv_detection_column1,hv_detection_column2, hv_ret;

        if (m_vector_graphics_shape_rectangle.size() >= 1){
            frankWidth(image,&m_hobject_show, row1, column1, row2, column2,&hv_ret,&hv_detection_column1,&hv_detection_column2);
        }
        else
        {
            HTuple hv_width,hv_height, hv_ret;
            GetImageSize(image,&hv_width,&hv_height);
            frankWidth(image,&m_hobject_show, 0, 0, hv_width, hv_height,&hv_ret,&hv_detection_column1,&hv_detection_column2);
        }




        int ret = hv_ret[0].I();

        if(ret<1)
        {
            return true;
            message = "frank error empty ";
            return false;
        }
        int  detection_column1 = hv_detection_column1[0].I();
        int  detection_column2 = hv_detection_column2[0].I();

        if (m_vector_graphics_shape_rectangle.size() >= 1){
            if(detection_column1==column1)
            {
                message = "frank error left exceed﻿";
                return false;
            }
            if(detection_column2==column2)
            {
                message = "frank error right exceed﻿";
                return false;
            }
        }

        int width = detection_column2- detection_column1;


        if(width>m_width_max)
        {
            message = "frank error" + QString::number(width);
            return false;
        }
        if(width<m_width_min)
        {
            message = "frank error" +QString::number(width);
            return false;
        }
		else
		{
			message = "frank width" + QString::number(width);
			return true;
		}

    }
    catch (HException &HDevExpDefaultException)
    {
        message = HDevExpDefaultException.ErrorMessage();
        return false;
    }


    return 1;

}

void FunctionFrankWidth::detectionImage()
{
    if(m_image.empty())
       {
           QMessageBox::information(nullptr,"","nop image");
           return;
       }

       QString message;


       HObject image = matToHImage(m_image);

       bool state = detection(image, message);

       if(state)
       {
           message += "OK";
       }

       Mat image_show;

       draw(m_image,image_show);

       QImage q_image = matToQImage(image_show);
       if (!q_image.isNull())
       {
           m_view->setImage(q_image, message);
       }

}

void FunctionFrankWidth::draw(Mat image_in, Mat& image_out)
{
	image_out = image_in.clone();
	if (image_out.channels() == 1)
	{
		cvtColor(image_out, image_out, COLOR_GRAY2BGR);
	}
	image_out = drawRegion(image_out,m_hobject_show, Scalar(0, 255, 0));
    GenEmptyRegion(&m_hobject_show);

}

void FunctionFrankWidth::loadParameter()
{
    try
    {
		int roi_number = m_qsettings->value(m_section + "/" + "roi_number", 0).toInt();
		if (roi_number > 0)
		{
			int i = 0;
			row1 = m_qsettings->value(m_section + "/" + "ROI" + QString::number(i) + "row1", 100).toInt();
			column1 = m_qsettings->value(m_section + "/" + "ROI" + QString::number(i) + "column1", 100).toInt();
			row2 = m_qsettings->value(m_section + "/" + "ROI" + QString::number(i) + "row2", 200).toInt();
			column2 = m_qsettings->value(m_section + "/" + "ROI" + QString::number(i) + "column2", 200).toInt();

			GraphicsShapeRectangleCirce* p = new GraphicsShapeRectangleCirce( column1, row1,  column2 - column1, row2 - row1, Qt::blue);
			p->setShapeType(0);
			p->setFilled(false);
			p->setZValue(101);
			m_view->m_scene->addItem(p);
			
			m_vector_graphics_shape_rectangle.push_back(p);
		}

        m_width_min = m_qsettings->value(m_section + "/" + "m_width_min").toInt();
        m_width_max = m_qsettings->value(m_section + "/" + "m_width_max").toInt();
        m_qspinbox_width_min->setValue(m_width_min);
        m_qspinbox_width_max->setValue(m_width_max);

    }
    catch(exception& error)
    {
        QMessageBox::critical(nullptr,error.what() , m_section + "para error");
    }
    return ;
}

void FunctionFrankWidth::saveParameter()
{
    try
        {

			m_qsettings->setValue(m_section + "/" + "roi_number", m_vector_graphics_shape_rectangle.size());
			if (m_vector_graphics_shape_rectangle.size() > 0)
			{
				int i = 0;
				QRectF qrectf = m_vector_graphics_shape_rectangle[i]->boundingRect();
				row1 = m_vector_graphics_shape_rectangle[i]->pos().y() + (int)qrectf.y();
				column1 = m_vector_graphics_shape_rectangle[i]->pos().x() + (int)qrectf.x();
				row2 = m_vector_graphics_shape_rectangle[i]->pos().y() + (int)(qrectf.y() + qrectf.height());
				column2 = m_vector_graphics_shape_rectangle[i]->pos().x() + (int)(qrectf.x() + qrectf.width());
				m_qsettings->setValue(m_section + "/" + "ROI" + QString::number(i) + "row1", row1);
				m_qsettings->setValue(m_section + "/" + "ROI" + QString::number(i) + "column1", column1);
				m_qsettings->setValue(m_section + "/" + "ROI" + QString::number(i) + "row2", row2);
				m_qsettings->setValue(m_section + "/" + "ROI" + QString::number(i) + "column2", column2);
			}

            m_width_min = m_qspinbox_width_min->value();
            m_width_max = m_qspinbox_width_max->value();
            m_qsettings->setValue(m_section + "/" + "m_width_min", m_width_min);
            m_qsettings->setValue(m_section + "/" + "m_width_max", m_width_max);




        }
        catch(exception& error)
        {
            QMessageBox::critical(nullptr,error.what() , m_section + "para error");
        }
    


}

bool FunctionFrankWidth::showDialog()
{
    QImage q_image = matToQImage(m_image);
    m_view->setImage(q_image,"");
    return true;
}



